﻿using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LServer.Core.LFMongoDB
{
    public abstract class LFUniqueIDBase
    {
        private FindOneAndUpdateOptions<LFUniqueEntity> options = new FindOneAndUpdateOptions<LFUniqueEntity> { IsUpsert = true };

        #region 子类需要实现的属性
        /// <summary>
        /// MongoClient
        /// </summary>
        protected abstract MongoClient Client
        {
            get;
        }

        /// <summary>
        /// 数据库名称
        /// </summary>
        protected abstract string DatabaseName
        {
            get;
        }

        /// <summary>
        /// 集合名称
        /// </summary>
        protected abstract string CollectionName
        {
            get;
        }

        /// <summary>
        /// 是否记录错误日志
        /// </summary>
        protected virtual bool CanLogError
        {
            get { return true; }
        }
        #endregion

        #region 获取文档集合 GetCollection
        private IMongoCollection<LFUniqueEntity> m_Collection = null;

        /// <summary>
        /// 获取文档集合
        /// </summary>
        /// <returns></returns>
        public IMongoCollection<LFUniqueEntity> GetCollection()
        {
            try
            {
                if (m_Collection == null)
                {
                    IMongoDatabase database = Client.GetDatabase(DatabaseName);
                    m_Collection = database.GetCollection<LFUniqueEntity>(CollectionName);
                }
                return m_Collection;
            }
            catch (Exception ex)
            {
                if (CanLogError)
                {
                    //LoggerMgr.Log(LoggerLevel.LogError, 0, true, ex.Message);
                }
                else
                {
                    throw ex;
                }
                return null;
            }
        }
        #endregion

        public long GetUniqueID(int type, int seq = 1)
        {
            var collection = GetCollection();
            LFUniqueEntity entity = collection.FindOneAndUpdate(
                Builders<LFUniqueEntity>.Filter.Eq(t => t.Type, type),
                Builders<LFUniqueEntity>.Update.Inc(t => t.CurrId, seq),
                options
                );
            return entity == null ? seq : entity.CurrId + seq;
        }
    }

    public class LFUniqueEntity
    {
        public ObjectId Id;

        public ushort Type;
        public long CurrId;
    }
}
